load("@rules_gazebo//gazebo:headers.bzl", "gz_configure_file", "gz_configure_header", "gz_export_header")
load("@rules_license//rules:license.bzl", "license")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_python//python:proto.bzl", "py_proto_library")
load(
    "//tools:gz_msgs_generate.bzl",
    "gz_proto_factory",
    "gz_proto_library",
)

package(
    default_applicable_licenses = [":license"],
    features = [
        "layering_check",
        "parse_headers",
    ],
)

license(
    name = "license",
    package_name = "gz-msgs",
)

licenses(["notice"])

exports_files([
    "LICENSE",
    "MODULE.bazel",
])

gz_configure_header(
    name = "Config",
    src = "core/include/gz/msgs/config.hh.in",
    out = "include/gz/msgs/config.hh",
    package_xml = "package.xml",
)

gz_export_header(
    name = "Export",
    out = "include/gz/msgs/Export.hh",
    export_base = "GZ_MSGS",
    lib_name = "gz-msgs",
)

public_headers_no_gen = glob([
    "core/include/gz/msgs/*.hh",
    "core/include/gz/msgs/convert/*.hh",
    "core/include/gz/msgs/detail/*.hh",
])

protos = glob(["proto/gz/msgs/*.proto"])

# Custom Gazebo Protoc plugin
cc_binary(
    name = "gz_msgs_gen",
    srcs = [
        "core/generator_lite/Generator.cc",
        "core/generator_lite/Generator.hh",
        "core/generator_lite/generator_main.cc",
    ],
    visibility = ["//:__subpackages__"],
    deps = [
        "@com_google_protobuf//:protobuf",
        "@com_google_protobuf//:protoc_lib",
        "@com_google_protobuf//src/google/protobuf/compiler:code_generator",
        "@com_google_protobuf//src/google/protobuf/io",
        "@com_google_protobuf//src/google/protobuf/io:printer",
    ],
)

# Create a library of our protobuf message files
proto_library(
    name = "gzmsgs_proto",
    srcs = protos,
    strip_import_prefix = "proto",
    visibility = ["//visibility:public"],
    deps = [
        "@com_google_protobuf//:any_proto",
    ],
)

py_proto_library(
    name = "gzmsgs_proto_py_pb2",
    visibility = ["//visibility:public"],
    deps = [":gzmsgs_proto"],
)

gz_proto_library(
    name = "gzmsgs_cc_proto",
    features = [
        # Layering check fails for clang build due to no module exporting
        # `port_def.inc` and `port_undef.inc`. Unfortunately, the bazel target
        # that exports these headers in protobuf is private.
        "-layering_check",
    ],
    proto_deps = [":gzmsgs_proto"],
    visibility = ["//visibility:public"],
    deps = [
        "@com_google_protobuf//:protobuf",
        "@com_google_protobuf//:protobuf_lite",
        "@com_google_protobuf//src/google/protobuf/io",
    ],
)

gz_proto_factory(
    name = "gzmsgs_proto_factory",
    cc_output = "core/src/RegisterMsgs.cc",
    hh_output = "include/gz/msgs/MessageTypes.hh",
    deps = [":gzmsgs_proto"],
)

public_headers = public_headers_no_gen + [
    "include/gz/msgs/config.hh",
    "include/gz/msgs/Export.hh",
    "include/gz/msgs/MessageTypes.hh",
]

cc_library(
    name = "gz-msgs",
    srcs = [
        "core/src/DynamicFactory.cc",
        "core/src/DynamicFactory.hh",
        "core/src/Factory.cc",
        "core/src/MessageFactory.cc",
        "core/src/RegisterMsgs.cc",
        "core/src/impl/InstallationDirectories.cc",
    ],
    hdrs = public_headers,
    copts = [
        "-fexceptions",
    ],
    includes = [
        "core/include",
        "core/src",
        "include",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":gzmsgs_cc_proto",
        ":gzmsgs_proto_factory",
        "@com_google_protobuf//:protobuf",
        "@gz-math",
        "@gz-utils//:Environment",
        "@gz-utils//:ImplPtr",
        "@gz-utils//:NeverDestroyed",
        "@tinyxml2",
    ],
)

# test_sources = glob(
#     include = ["src/*_TEST.cc"],
#     exclude = [],
# )

# [cc_test(
#     name = src.replace("/", "_").replace(".cc", "").replace("src_", ""),
#     srcs = [src],
#     data = [
#         "test/desc",
#     ],
#     defines = [
#         'GZ_MSGS_TEST_PATH=\\"msgs/test\\"',
#     ],
#     deps = [
#         ":msgs",
#         GZ_ROOT + "common/testing",
#         "@gtest",
#         "@gtest//:gtest_main",
#     ],
# ) for src in test_sources]

cc_test(
    name = "INTEGRATION_headers",
    srcs = ["test/integration/headers.cc"],
    deps = [
        ":gzmsgs_cc_proto",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "INTEGRATION_image_msg",
    srcs = ["test/integration/image_msg.cc"],
    deps = [
        ":gzmsgs_cc_proto",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

# cc_test(
#     name = "INTEGRATION_Utility",
#     srcs = ["test/integration/Utility_TEST.cc"],
#     deps = [
#         ":msgs",
#         GZ_ROOT + "common/testing",
#         "@gtest",
#         "@gtest//:gtest_main",
#     ],
# )

# cc_test(
#     name = "INTEGRATION_Factory",
#     srcs = ["test/integration/Factory_TEST.cc"],
#     data = ["test/desc/stringmsg.desc"],
#     defines = [
#         'GZ_MSGS_TEST_PATH=\\"msgs/test\\"',
#     ],
#     deps = [
#         ":msgs",
#         GZ_ROOT + "common/testing",
#         "@gtest",
#         "@gtest//:gtest_main",
#     ],
# )

# cc_test(
#     name = "INTEGRATION_descriptors",
#     srcs = ["test/integration/descriptors.cc"],
#     data = ["test/desc"],
#     defines = [
#         'GZ_MSGS_TEST_PATH=\\"msgs/test\\"',
#     ],
#     deps = [
#         ":msgs",
#         GZ_ROOT + "common/testing",
#         "@gtest",
#         "@gtest//:gtest_main",
#     ],
# )

gz_configure_file(
    name = "msgs_yaml",
    src = "conf/msgs.yaml.in",
    out = "msgs.yaml",
    defines = [
        "PROJECT_NAME_NO_VERSION_LOWER=msgs",
        "gz_library_path=msgs/cmdmsgs",
    ],
    package_xml = "package.xml",
)

gz_configure_file(
    name = "msgs_rb",
    src = "core/cmd/cmdmsgs.rb.in",
    out = "cmdmsgs.rb",
    defines = [
        "executable_location=cmd-gz-msgs",
    ],
    package_xml = "package.xml",
)

cc_binary(
    name = "cmd-gz-msgs",
    srcs = ["core/cmd/msgs_main.cc"],
    data = [
        "cmdmsgs.rb",
        "msgs.yaml",
        ":gzmsgs_proto",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":gz-msgs",
        "@gz-utils//cli:GzFormatter",
        "@gz-utils//cli:cli11",
    ],
)
